﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form_LED : Form
    {
        SynchronizationContext sync1 = null;
        SynchronizationContext sync2 = null;
        SynchronizationContext sync3 = null;

        public Form_LED()
        {
            InitializeComponent();
            startThread();
            sync1 = SynchronizationContext.Current;
            sync2 = SynchronizationContext.Current;
            sync3 = SynchronizationContext.Current;
        }

        Thread th1 = null;
        Thread th2 = null;

        void updateText(object obj) // 线程助手 
        {
            string[] str = SerialPort.GetPortNames();

            for (int y = 0; y < str.Length; y++)
            {
                if (comboBox_串口号.Items.Contains(str[y]) == false)
                    comboBox_串口号.Items.Add(str[y]);
            }

            for (int y = 0; y < comboBox_串口号.Items.Count; y++)
            {
                if (str.Contains(comboBox_串口号.Items[y]) == false)
                {
                    if (serialPort_串口.IsOpen)
                        serialPort_Clear(serialPort_串口);
                    comboBox_串口号.Items.Remove(comboBox_串口号.Items[y]);
                }
            }
        }

        void startThread() // 线程启动函数
        {
            th1 = new Thread(myTast);
            if (th1.IsAlive)
                return;
            th1.Start();
        }

        void Hot_Plug_startThread()
        {
            th2 = new Thread(Hot_Plug);
            th2.Start();
        }

        void myTast() // 线程函数
        {
            while (true)
            {
                sync1.Post(updateText, null);
                Thread.Sleep(100);
            }
        }

        void Read_update(object obj)
        {
            Read_Data(obj);
        }

        void serialPort_Open(SerialPort obj)
        {
            try
            {
                obj.PortName = comboBox_串口号.Text;
                obj.Open();
                Hot_Plug_startThread();
                button_连接.Text = "关闭";
                label_变化灯.ForeColor = Color.Red;
            }
            catch (Exception)
            {
                MessageBox.Show("串口被占用,或不存在");
            }
        }

        void serialPort_Clear(SerialPort obj)
        {
            obj.Close();

            button_连接.Text = "打开";
            label_变化灯.ForeColor = Color.Black;

            button_LED1.Text = "打开";
            label_LED1.ForeColor = Color.Black;

            button_LED2.Text = "打开";
            label_LED2.ForeColor = Color.Black;

            button_LED3.Text = "打开";
            label_LED3.ForeColor = Color.Black;

            button_LED4.Text = "打开";
            label_LED4.ForeColor = Color.Black;
        }

        void serserialPort_Send(SerialPort obj, string str)
        {
            if (serialPort_串口.IsOpen)
                obj.Write(str);
        }

        void Read_Data(object obj)
        {
            string recvStr = (string)obj;

            if (recvStr.Substring(0, 1) == "0")
            {
                button_LED1.Text = "关闭";
                label_LED1.ForeColor = Color.Blue;
            }
            else if (recvStr.Substring(0, 1) == "1")
            {
                button_LED1.Text = "打开";
                label_LED1.ForeColor = Color.Black;
            }
            if (recvStr.Substring(1, 1) == "0")
            {
                button_LED2.Text = "关闭";
                label_LED2.ForeColor = Color.Blue;
            }
            else if (recvStr.Substring(1, 1) == "1")
            {
                button_LED2.Text = "打开";
                label_LED2.ForeColor = Color.Black;
            }
            if (recvStr.Substring(2, 1) == "0")
            {
                button_LED3.Text = "关闭";
                label_LED3.ForeColor = Color.Blue;
            }
            else if (recvStr.Substring(2, 1) == "1")
            {
                button_LED3.Text = "打开";
                label_LED3.ForeColor = Color.Black;
            }
            if (recvStr.Substring(3, 1) == "0")
            {
                button_LED4.Text = "关闭";
                label_LED4.ForeColor = Color.Blue;
            }
            else if (recvStr.Substring(3, 1) == "1")
            {
                button_LED4.Text = "打开";
                label_LED4.ForeColor = Color.Black;
            }
        }

        void Hot_Plug()
        { 
            while (true)
            {   
                if (serialPort_串口.IsOpen)
                {
                    Thread.Sleep(100);

                    if (!(serialPort_串口.IsOpen))
                    {
                        if (button_连接.Text == "关闭")
                        {
                            startThread();
                            sync3.Post(Hot_Plug_Assistant, null);
                        }
                        break;
                    }
                        
                    int data_size_old = 0;
                    int data_size = serialPort_串口.BytesToRead;

                    if (data_size != 0)
                    {
                        data_size_old = data_size;
                        Thread.Sleep(5);
                        data_size = serialPort_串口.BytesToRead;
                        if (data_size_old == data_size)
                        {
                            byte[] recvBuf = new byte[data_size];
                            String recvStr = "";
                            serialPort_串口.Read(recvBuf, 0, data_size); // 读取串口缓存中的数据
                            recvStr = System.Text.Encoding.Default.GetString(recvBuf, 0, data_size);

                            sync2.Post(Read_update, recvStr);
                        }
                    }
                }
            }
        }

        void Hot_Plug_Assistant(object obj)
        {
            Hot_Plug_ComboBox_Clear(serialPort_串口);
        }

        void Hot_Plug_ComboBox_Clear(SerialPort obj)
        {
            obj.Close();

            comboBox_串口号.Items.Clear();
            comboBox_串口号.Text = "";

            button_连接.Text = "打开";
            label_变化灯.ForeColor = Color.Black;

            button_LED1.Text = "打开";
            label_LED1.ForeColor = Color.Black;

            button_LED2.Text = "打开";
            label_LED2.ForeColor = Color.Black;

            button_LED3.Text = "打开";
            label_LED3.ForeColor = Color.Black;

            button_LED4.Text = "打开";
            label_LED4.ForeColor = Color.Black;
        }

        // protected override void WndProc(ref Message m)
        //{
        //    if (m.Msg == 0x0219)
        //    {//设备被拔出
        //        if (m.WParam.ToInt32() == 0x8004)//usb串口
        //        {
        //            //if (对串口进行操作)
        //            //{//产生异常
        //            //      关闭串口
        //            //}
        //            MessageBox.Show("USB转串口拔出");
                   
        //        }
        //    }
        //    base.WndProc(ref m);
        //}

        private void button_连接_Click(object sender, EventArgs e)
        {
            if (button_连接.Text == "打开")
            {
                serialPort_Open(serialPort_串口);
            }
            else
            {
                serialPort_Clear(serialPort_串口);
            }
        }

        private void button_LED1_Click(object sender, EventArgs e)
        {
            if (serialPort_串口.IsOpen)
            {
                if (button_LED1.Text == "打开")
                {
                    serserialPort_Send(serialPort_串口, "LED1ON");
                }
                else
                {
                    serserialPort_Send(serialPort_串口, "LED1OFF");
                }
            }
        }

        private void button_LED2_Click(object sender, EventArgs e)
        {
            if (serialPort_串口.IsOpen)
            {
                if (button_LED2.Text == "打开")
                {
                    serserialPort_Send(serialPort_串口, "LED2ON");
                }
                else
                {
                    serserialPort_Send(serialPort_串口, "LED2OFF");
                }
            }
        }

        private void button_LED3_Click(object sender, EventArgs e)
        {
            if (serialPort_串口.IsOpen)
            {
                if (button_LED3.Text == "打开")
                {
                    serserialPort_Send(serialPort_串口, "LED3ON");
                }
                else
                {
                    serserialPort_Send(serialPort_串口, "LED3OFF");
                }
            }
        }

        private void button_LED4_Click(object sender, EventArgs e)
        {
            if (serialPort_串口.IsOpen)
            {
                if (button_LED4.Text == "打开")
                {
                    serserialPort_Send(serialPort_串口, "LED4ON");
                }
                else
                {
                    serserialPort_Send(serialPort_串口, "LED4OFF");
                }
            }
        }

        private void label_变化灯_Click(object sender, EventArgs e)
        {

        }

        private void Form_LED_Load(object sender, EventArgs e)
        {

        }

        private void button_关闭_Click(object sender, EventArgs e)
        {
            System.Environment.Exit(0);
        }

        private void comboBox_串口号_SelectedIndexChanged(object sender, EventArgs e)
        {

        }
    }
}
